Memory management that makes your code size smaller

aka: How to get rid of memory leaks without any efforts whatsoever

By snq/aardbei

After reading Chris Dragan's article about a memory leak detector in Hugi 26, I decided to play around a bit with this idea, and came up with the perfect solution for all lazy coders: a memory manager, one that might actually make your code size smaller as well. Always got intros in the back of my head :) Oh btw this is my first article ever, so it might suck :)

So, where to start?
Well, as you read in Chris' article, you can override the standard new and delete operators. That we like. So now let's write a small memory manager, I won't give you a complete source because I'm sure you can figure some parts out yourself :)
Anyway, here's a pseudo-code version of what your memmanager.cpp would look like:

// #undef these, in case you have overridden them in your header.
#undef malloc
#undef free
// this function allocates a memory block for us.
// in other words: this is your new new/malloc.
void *MemAlloc( size_t size )
{
 // Allocate requested amount of memory.
 void *ptr = malloc( size );
 // you can do some error handling here..
 if( !ptr ) MsgBox("are you rasmus?");
 // Log the newly allocated memory block.
 MemLogPtr( ptr );
 return ptr;
}
// we keep track of everything we allocate in some way.
// call this function for everything you allocate.
void MemLogPtr( void *ptr )
{
 // Add [ptr] to our pointer list
 ...
}
// free the memory block again.
void MemFree( void *ptr )
{
 // Free the memory.
 free( ptr );
 // And remove the pointer from the list.
 ...
}
// free everything in our pointer list.
void MemFreeAll()
{
 // Free all remaining pointers.
 for( all logged pointers )
 {
  free( ptr );
  // And remove it from the list, or don't.
  // This is probably one of the last things your app does, so you might
  // not find it necessary to clean up your list. However if you don't want
  // to get a leak in your memory manager and you use a linked list, free it
  // here as well :)
  ...
 }
}

Don't forget the #undef malloc/free in your cpp file! You'll end up with a crash if you don't. Your MemAlloc/MemFree will keep on calling themselves forever (actually just a fraction of a second until your app crashes). How you store the pointer info is up to you. I use a linked list because I think it's the most convenient way, but you can get away with an array as well. Just keep in mind that you allocate more often than you think, so get a big array :)

Now, what about that overriding stuff? Here you go, put this in some header file that you include from all your other files:

inline void* operator new( size_t size ) { return MemAlloc( size ); }
inline void operator delete( void *ptr ) { MemFree( ptr ); }
// you can override malloc() and free() as well.
#define malloc MemAlloc
#define free MemFree

There's no need to do anything else, all your "new DWORD[256*256]", delete and malloc etc will now automatically use your memory manager. And if for some reason you don't want to use the memory manager, you just comment out the overrides. As easy as that. Plug&Play :)

Another thing, you might use functions like strdup() that allocate memory themselves. You might want to override those as well:

#define strdup MyOwnStrDupThatCallsMemLogPtr

We're as good as done now! One last thing you'll need to do is call MemFreeAll() just before you exit your app to clean up all memory that you have allocated but not freed yet.

So now you're wondering: how can this possibly make my code size smaller? Think about it. You can remove every delete/free() you have in your app without causing a huge memory leak. As I said before, you have (or should have anyway) more than you think! Don't go wild tho, please do remove (bigger) temporary blocks, because otherwise it'll just sit around taking up memory until the app is closed.

Another approach for size optimization would be to let Windows clean up your shit after you. I'm not sure about other versions, but at least Win2k seems to do a very good job when it comes cleaning up your mess when your app is unloaded. A quick way to do that:

// That's right. We don't delete anything :)
inline void operator delete( void *ptr ) { }

And you don't override the new operator. For minimal code size this is nice, other than that it really isn't. Anyway, this is a VERY VERY dirty way to do things, and I'm sure Jace/TBL would come and beat you (or me) up with a stick if you ever dare to use this :)
And of course you could also just comment out all your delete calls but this is a faster way :)

Also, be aware that this memory manager is not perfect. There are a lot of Windows API calls that allocate memory as well, in some way. And they of course don't use your nice MemAlloc() function. A very good way to find/get rid of those leaks (as well as any other kind of leaks) is using BoundsChecker. Then when you found them, you can redefine them like with strdup.

That's all for now!

Comments and/or questions are always welcome :)

snq/aardbei